<template>
  <div class="targetTable">
    <el-form ref="elform" :model="formData" size="small" :rules="rules" @submit.native.prevent>
      <el-table
        :ref="proRef"
        v-loading="loading"
        :row-key="rowkey"
        :reserve-selection="true"
        :show-header="showHeader"
        :data="formData.realTableData"
        :row-class-name="tableRowClassName"
        :height="tableHeight"
        :row-style="{ height: rowheight || '' }"
        element-loading-text="加载中"
        :style="{ width: '100%', minHeight: minHeight }"
        :empty-text="noDataShow"
        v-bind="$attrs"
        :show-overflow-tooltip="showOverflowTooltip"
        @row-click="singleElection"
        @select="selectElm"
        @selection-change="handleSelectionChange"
        @select-all="selectAll">
        <!-- 空数据展示，可以不用 -->
        <template slot="empty">
          <!-- <img src="@/assets/kongshuju.png" alt="" style="width:50px;height:50px;" class="mt-20"> -->
          <p class="noCart">{{ noDataShow }}</p>
        </template>
        <!-- 是否有全选列 -->
        <el-table-column
          v-if="selection"
          :fixed="commonFixed ? '' : false"
          :selectable="selectFn"
          align="center"
          width="45"
          type="selection" />
        <!-- 是否有单选框 -->
        <el-table-column v-if="radiobox" align="center" width="35">
          <template slot-scope="scope">
            <!-- 可以手动的修改label的值，从而控制选择哪一项 -->
            <el-radio v-model="templateSelection" class="radio" :label="scope.row[identifier]">&nbsp;</el-radio>
          </template>
        </el-table-column>

        <!-- 是否显示序号 -->
        <el-table-column
          v-if="showIndex"
          label="序号"
          align="center"
          :fixed="commonFixed ? '' : false"
          width="55"
          type="index"
          :index="indexMethod" />
        <!-- 是否有展开列 -->
        <el-table-column v-if="expand" type="expand" width="1">
          <template slot-scope="props">
            <hk-table
              style="margin-left: 30px"
              :table-data="props.row[identifier]"
              :table-columns="expandColumns"
              :operate="sonOperate"
              :show-pag="false" />
          </template>
        </el-table-column>
        <!-- prop是对应列内容的字段名 width是对应列宽度 sortable是是否排序 label是对应列名称 -->

        <el-table-column
          v-for="(item, index) in tableColumns"
          v-if="!item.show"
          :key="index"
          :sortable="item.sortable"
          :prop="item.param"
          :width="item.width ? item.width : ''"
          :label="item.label"
          :show-overflow-tooltip="item.showTip"
          :align="item.align || 'left'"
          :fixed="item.fixed"
          :render-header="item.addRedStar">
          <!-- 具名插槽 -->
          <template slot-scope="scope">
            <template v-if="item.type == 'expand'">
              <span class="tbTextButton" @click="toogleExpand(scope.row)">
                <i :class="!scope.row.expandStyle ? 'el-icon-arrow-right' : 'el-icon-arrow-down'" />
                {{ scope.row[item.param] }}
              </span>
            </template>
            <template v-else-if="item.type == 'slot'">
              <slot :name="item.param" :row="isNeedIndex ? scope : scope.row" />
            </template>
            <template v-else-if="item.type == 'dict'">
              <dict-label :options="dictList[item.list]" :value="scope.row[item.param]" />
            </template>

            <el-form-item
              v-else-if="item.type"
              :rules="item.rules && rules[item.rules]"
              :prop="`realTableData.${scope.$index}.${item.param}`">
              <template v-if="item.type == 'input'">
                <el-input
                  v-model="scope.row[item.param]"
                  :disabled="item.disabled"
                  :clearable="true"
                  style="width: 100%"
                  :maxlength="item.maxlength"
                  placeholder="请输入"
                  @blur="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)" />
              </template>
              <template v-else-if="item.type == 'textarea'">
                <el-input
                  v-model="scope.row[item.param]"
                  type="textarea"
                  :clearable="true"
                  style="width: 100%"
                  :disabled="item.disabled"
                  :maxlength="item.maxlength" />
              </template>
              <template v-else-if="item.type == 'select'">
                <el-select
                  v-model="scope.row[item.param]"
                  :clearable="true"
                  placeholder="请选择"
                  :disabled="item.disabled"
                  v-bind="item.attrs"
                  filterable
                  style="width: 100%"
                  @change="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)"
                  @focus="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)">
                  <el-option
                    v-for="(el, index) in dictList[item.list]"
                    :key="index"
                    :label="el.label"
                    :value="el.value" />
                </el-select>
              </template>
              <template v-else-if="item.type == 'ownSelect'">
                <el-select
                  v-model="scope.row[item.param]"
                  :clearable="true"
                  placeholder="请选择"
                  :disabled="item.disabled"
                  v-bind="item.attrs"
                  filterable
                  style="width: 100%"
                  @change="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)"
                  @focus="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)">
                  <el-option v-for="(el, index) in scope.row[item.list]" :key="index" :label="el" :value="el" />
                </el-select>
              </template>
              <!--    日期选择器    -->
              <el-date-picker
                v-else-if="item.type == 'datePicker'"
                v-model="scope.row[item.param]"
                style="width: 100%"
                type="date"
                placeholder="选择日期"
                :disabled="item.disabled"
                :value-format="item.format" />
              <!--   计数器   -->
              <el-input-number
                v-if="item.type == 'number'"
                v-model="scope.row[item.param]"
                :min="item.min || 0"
                style="width: 100%"
                controls-position="right"
                :max="item.max"
                :disabled="item.disabled"
                v-bind="item.attrs" />
              <!-- 开关 -->
              <el-switch
                v-if="item.type == 'switch'"
                v-model="scope.row[item.param]"
                :active-value="item.activeValue"
                :inactive-value="item.inactiveValue"
                :disabled="item.disabled"
                @change="handleEvent(scope.row, item.param, scope.row[item.param], scope.$index)">
              </el-switch>
            </el-form-item>

            <template v-else>
              <!-- <span v-if="!item.hidden">{{ scope.row[item.param ] }}</span> -->
              <span v-if="!item.hidden">{{ scope.row[item.param] }}</span>
            </template>
          </template>
        </el-table-column>
        <!-- 操作插槽 -->
        <el-table-column
          v-if="operate"
          label="操作"
          align="center"
          :fixed="commonFixed ? 'right' : false"
          :width="operateWidth">
          <template slot-scope="scope">
            <slot :row="isNeedIndex ? { row: scope.row, index: scope.$index } : scope.row" name="operate" />
          </template>
        </el-table-column>
      </el-table>
    </el-form>

    <!-- 分页器 -->
    <pagination
      v-if="total >= 0 && showPag"
      :total="Number(total)"
      :page.sync="queryParamsData.current"
      :limit.sync="queryParamsData.size"
      :pager-count="pagerCount"
      v-bind="$attrs"
      @pagination="changePage" />
  </div>
</template>

<script>
import dictLabel from '../Common/dictLabel.vue'
export default {
  name: 'HkTable',
  components: {
    dictLabel,
  },
  props: {
    rules: {
      type: Object,
      default: () => {},
    },
    dictList: {
      type: Object,
      default: () => {},
    },
    isNeedIndex: {
      type: Boolean,
      default() {
        return false
      },
    },
    // 是否显示单选框
    radiobox: {
      type: Boolean,
      default: false,
    },
    proRef: {
      type: String,
      default: 'table',
    },
    total: {
      // eslint-disable-next-line vue/require-prop-type-constructor
      type: Number | String,
      default: 0,
    },
    pagerCount: {
      // eslint-disable-next-line vue/require-prop-type-constructor
      type: Number,
      default: 7,
    },

    rowkey: {
      // eslint-disable-next-line vue/require-prop-type-constructor
      type: String | Function,
      default: '',
    },
    selectThing: {
      type: Boolean,
      default: false,
    },
    sonOperate: {
      type: Boolean,
      default: true,
    },
    showOverflowTooltip: {
      type: Boolean,
      default: true,
    },
    showHeader: {
      // 是否显示表头
      type: Boolean,
      default: true,
    },
    loading: {
      // 预加载
      type: Boolean,
      default: false,
    },
    selectFn: {
      // 全选禁用方法
      type: Function,
      default: () => {
        return true
      },
    },
    tableData: {
      // 表格数据
      type: Array,
      default: () => {
        return []
      },
    },
    tableColumns: {
      // 表头数据
      type: Array,
      default: () => {
        return []
      },
    },
    expandColumns: {
      // 表头数据
      type: Array,
      default: () => {
        return []
      },
    },
    expand: {
      // 展开
      type: Boolean,
      default: false,
    },
    selection: {
      // 全选
      type: Boolean,
      default: false,
    },
    selectionFixed: {
      // 全选是否固定
      type: Boolean,
      default: false,
    },
    // 前面和操作面是否固定
    commonFixed: {
      // 全选是否固定
      type: Boolean,
      default: false,
    },
    showIndex: {
      // 顺序
      type: Boolean,
      default: false,
    },
    operate: {
      // 操作
      type: Boolean,
      default: false,
    },
    // 操作栏位的宽度
    operateWidth: {
      // 操作
      type: String | Number,
      default: '',
    },
    tableHeight: {
      // 高度
      type: [Number, String],
      default: () => null,
    },
    rowheight: {
      // 行高
      type: String,
      default: () => null,
    },
    minHeight: {
      type: String,
      default: () => '0px',
    },
    noDataShow: {
      // table中间无数据展示
      type: String,
      default: () => '暂无数据',
    },
    // 分页器部分
    queryParams: {
      type: Object,
      default: () => {
        return { current: 1, size: 10 }
      },
    },
    // 是否显示分页器
    showPag: {
      type: Boolean,
      default: true,
    },
    // 标识符
    identifier: {
      type: String,
      default: 'id',
    },
  },
  data() {
    return {
      isloading: this.loading,

      templateSelection: '',
      checkList: [],
      formData: {
        realTableData: [],
      },
    }
  },
  computed: {
    queryParamsData() {
      return this.queryParams
    },
  },
  watch: {
    tableData: {
      handler(newsVal) {
        this.getList()
      },
      deep: true,
    },
    'formData.realTableData': {
      handler(newsVal) {
        this.showSelected()
      },
      deep: true,
    },
    total: {
      handler(newsVal, oldValue) {
        if (this.queryParamsData.current > 1 && newsVal % this.queryParamsData.size == 0 && newsVal < oldValue) {
          this.queryParamsData.current--
          this.changePage()
        }
      },
    },

    // templateSelection: {
    //   handler(newsVal) {
    //  console.log('tem',newsVal);
    //   },
    //  immediate:true
    // }
    queryParams: {
      handler(newsVal, oldValue) {
        if (!(newsVal?.scrollToTop || this.loading)) return
        this.$nextTick(() => {
          this.$refs.table.bodyWrapper.scrollTop = 0
        })
      },
      immediate: true,
      deep: true,
    },
  },
  mounted() {
    this.getList()
    this.showSelected()
  },
  methods: {
    // 给表头加必填符号*
    addRedStar(h, { column }) {
      return [h('span', { style: 'color: red' }, '*'), h('span', ' ' + column.label)]
    },

    // 获取列表
    getList() {
      // this.tableData.forEach((element) => {
      //   for (const key in element) {
      //     element[key] = element[key] || '—'
      //   }
      // })
      this.formData.realTableData = this.tableData
    },
    subData() {
      this.formData.realTableData = this.tableData
      this.$emit('emitData', this.formData.realTableData)
    },
    // 分页
    changePage() {
      /* const tableBodys = $('.el-table__fixed-body-wrapper .el-table__body')
      console.log(tableBodys.length)
      for (let i = 0; i < tableBodys.length; i++) {
        tableBodys[i].scrollTop = 0
      } */
      this.$refs.table.bodyWrapper.scrollTop = 0
      this.$emit('changePage', {
        current: this.queryParamsData.current,
        size: this.queryParamsData.size,
      })
    },
    indexMethod(index) {
      if (!this.queryParamsData.current || !this.queryParamsData.size) {
        return index + 1
      } else {
        this.queryParamsData.current = this.queryParamsData.current >= 1 ? this.queryParamsData.current : 1
        return index + (this.queryParamsData.current - 1) * this.queryParamsData.size + 1
      }
    },
    // 单选
    singleElection(row) {
      this.templateSelection = row[this.identifier]
      this.checkList = this.tableData.filter((item) => item[this.identifier] === row[this.identifier])
      this.$emit('singleElection', this.checkList[0])
    },
    // 全部多选
    selectAll(selection) {
      this.formData.realTableData.forEach((i) => {
        this.selectElm(selection, i)
      })
    },

    // 选择变化
    handleSelectionChange(val) {
      this.$emit('handleSelectionChange', val)
    },

    // 筛选数据显示为选中
    showSelected() {},
    // 设置表格选中项
    toggleRow(item) {
      this.formData.realTableData.forEach((i) => {
        if (i[this.identifier] === item[this.identifier]) {
          this.$nextTick(() => {
            this.$refs.table.toggleRowSelection(i, true)
          })
        }
      })
    },
    // 获取所有选中的信息
    selectElm(elm, row) {
      const query = {}
      const isInside = elm.some((i) => i[this.identifier] === row[this.identifier])
      if (isInside) {
        query.addItem = row
      } else {
        query.removeItem = row
      }
      this.$emit('selectElm', query)
    },
    // 展开折叠面板
    toogleExpand(row) {
      if (!row.expandStyle) {
        row.expandStyle = true
      } else row.expandStyle = false
      const _this = this
      const $table = _this.$refs.table
      _this.formData.realTableData.map((item, index) => {
        if (row.id !== item.id) {
          item.expandStyle = false
          $table.toggleRowExpansion(item, false)
        }
      })
      $table.toggleRowExpansion(row)
    },
    // 清空选中项
    clearSelection() {
      this.$refs['table'].clearSelection()
    },
    // 按钮点击事件
    // methods方法名 row当前点击列数据 index当前点击的index
    handleButton(methods, row, index) {
      this.$emit('clickButton', { methods: methods, row: row, index: index })
    },

    tableRowClassName(row, rowIndex) {
      // 有空优化
      if (this.$parent.tableRowColor) {
        return this.$parent.tableRowColor(row, rowIndex)
      }
    },
    // input输入事件
    handleEvent(row, param, val, index, type) {
      const query = { row, param, val, index }
      this.$emit('handleEvent', query)
      if (!type) return
      this.validateSome(`realTableData.${index}.${param}`)
    },
    // 验证单项
    validateSome(field) {
      console.log(518, field)
      this.$nextTick(() => {
        this.$refs.elform.validateField(field)
      })
    },
    // 验证表格内部表单
    async regRules() {
      return new Promise((resolve) => {
        this.$refs.elform
          .validate()
          .then(() => {
            resolve(true)
          })
          .catch(() => {
            this.$message.error('请按要求补全数据')
          })
      })
    },
  },
}
</script>

<style lang="scss" scoped>
#app.dark-theme {
  .pagination-container {
    background: transparent !important;
  }
}
.targetTable {
  flex: 1;
  position: relative;
  // padding-bottom: 20px;
  display: flex;
  flex-direction: column;
  height: 100%;

  .el-form {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: auto;
  }
  .el-table {
    flex: 1;
    overflow: auto;
  }
}
.el-form .el-form-item {
  margin: 5px 0 13px;
}
.tbTextButton {
  cursor: pointer;
}
::v-deep {
  .el-form-item__error {
    font-size: 10px;
  }
  // .el-table .cell.el-tooltip{
  //   overflow: visible;
  // }
  .el-table__expand-icon {
    display: none;
  }
  .cell {
    white-space: nowrap;
  }
  .el-table__cell {
    padding: 7px 0 !important;
  }
  .el-table--border {
    border-right: 1px solid #dfe6ec;
    border-bottom: 1px solid #dfe6ec;
  }
  .pagination-container {
    padding: 20px 10px 0 !important;
  }
  .el-pagination {
    position: relative;
    text-align: right;
  }
}
</style>
